package cyx.example.ddd.interfaces.order.facade;

import cyx.example.ddd.application.order.command.CreateOrderCommand;
import cyx.example.ddd.application.order.command.OrderCommandService;
import cyx.example.ddd.application.order.dto.OrderDTO;
import cyx.example.ddd.application.order.dto.OrderStatisticsDTO;
import cyx.example.ddd.application.order.query.OrderPageQuery;
import cyx.example.ddd.application.order.query.OrderPageResult;
import cyx.example.ddd.application.order.query.OrderQuery;
import cyx.example.ddd.application.order.query.OrderQueryService;
import cyx.example.ddd.interfaces.common.Result;
import cyx.example.ddd.interfaces.order.dto.CreateOrderRequest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.LocalDate;
import java.util.Currency;
import java.util.List;
import java.util.stream.Collectors;

@Api(tags = "订单管理")
@RestController
@RequestMapping("/api/orders")
@RequiredArgsConstructor
public class OrderFacade {
    private final OrderCommandService orderCommandService;
    private final OrderQueryService orderQueryService;

    @ApiOperation("创建订单")
    @PostMapping
    public Result<OrderDTO> createOrder(@Valid @RequestBody CreateOrderRequest request) {
        CreateOrderCommand command = new CreateOrderCommand();
        command.setUserId(request.getUserId());
        command.setCurrency(Currency.getInstance(request.getCurrency()));
        command.setItems(request.getItems().stream()
                .map(item -> {
                    CreateOrderCommand.OrderItemCommand itemCommand = new CreateOrderCommand.OrderItemCommand();
                    itemCommand.setProductId(item.getProductId());
                    itemCommand.setProductName(item.getProductName());
                    itemCommand.setUnitPrice(item.getUnitPrice());
                    itemCommand.setQuantity(item.getQuantity());
                    return itemCommand;
                })
                .collect(Collectors.toList()));

        return Result.success(orderCommandService.createOrder(command));
    }

    @ApiOperation("查询订单")
    @GetMapping("/{orderId}")
    public Result<OrderDTO> getOrder(@PathVariable String orderId) {
        return orderQueryService.findById(orderId)
                .map(Result::success)
                .orElse(Result.error("404", "订单不存在"));
    }

    @ApiOperation("查询用户订单列表")
    @GetMapping("/user/{userId}")
    public Result<List<OrderDTO>> getUserOrders(@PathVariable String userId) {
        return Result.success(orderQueryService.findByUserId(userId));
    }

    @ApiOperation("条件查询订单")
    @PostMapping("/search")
    public Result<List<OrderDTO>> searchOrders(@RequestBody OrderQuery query) {
        return Result.success(orderQueryService.findByConditions(query));
    }

    @ApiOperation("分页查询订单")
    @PostMapping("/page")
    public Result<OrderPageResult> getOrderPage(@RequestBody OrderPageQuery pageQuery) {
        return Result.success(orderQueryService.findByPage(pageQuery));
    }

    @ApiOperation("获取订单统计")
    @GetMapping("/statistics")
    public Result<OrderStatisticsDTO> getOrderStatistics(
            @RequestParam LocalDate startDate,
            @RequestParam LocalDate endDate) {
        return Result.success(orderQueryService.getStatistics(startDate, endDate));
    }

    @ApiOperation("支付订单")
    @PostMapping("/{orderId}/pay")
    public Result<Void> payOrder(@PathVariable String orderId) {
        orderCommandService.payOrder(orderId);
        return Result.success();
    }

    @ApiOperation("取消订单")
    @PostMapping("/{orderId}/cancel")
    public Result<Void> cancelOrder(@PathVariable String orderId, @RequestParam String reason) {
        orderCommandService.cancelOrder(orderId, reason);
        return Result.success();
    }

    @ApiOperation("确认订单")
    @PostMapping("/{orderId}/confirm")
    public Result<Void> confirmOrder(@PathVariable String orderId) {
        orderCommandService.confirmOrder(orderId);
        return Result.success();
    }

    @ApiOperation("开始配送")
    @PostMapping("/{orderId}/shipping")
    public Result<Void> startShipping(@PathVariable String orderId) {
        orderCommandService.startShipping(orderId);
        return Result.success();
    }

    @ApiOperation("完成订单")
    @PostMapping("/{orderId}/complete")
    public Result<Void> completeOrder(@PathVariable String orderId) {
        orderCommandService.completeOrder(orderId);
        return Result.success();
    }
}